# 
# Used in ActiveResource classes to enable access via OAuth credentials
# 
# e.g. 
#   ./script/generate oauth_consumer SampleConsumer
#   
#   class Friend < ActiveResource::Base
#     acts_as_oauth_resource :for => SampleConsumer
#
#   end
#
module ActiveResource
  module Acts
    module Connection
      def oauth_instance=(oauth_instance)
        @oauth_instance = oauth_instance
      end

      # 
      # would've loved to merely overwrite authorization_header()
      # but we need 'path' value, only avail at request()
      # 
      def request(method, path, *arguments)
        request_with_oauth_headers(method.to_s.upcase, path, 
          ([:post, :put].include?(method) ? arguments[1] : arguments[0]))
      end

      def request_with_oauth_headers(method, path, headers)
        access_token = OAuth::AccessToken.new(@oauth_instance.class.new_consumer, @oauth_instance.oauth_token, @oauth_instance.oauth_token_secret)
        access_token.request(method.to_s.downcase.to_sym, path, headers)
      end
    end

    module OAuthResource
      def self.included(base)
        base.extend ClassMethods
      end

      module ClassMethods
        def acts_as_oauth_resource
          return if self.included_modules.include?(ActiveResource::Acts::OAuthResource::ActMethods)
          class_eval do
            include ActiveResource::Acts::OAuthResource::ActMethods
            class << self
              def connection_with_oauth(*args)
                c = connection_without_oauth(*args)
                if self.oauth_instance
                  c.extend ActiveResource::Acts::Connection
                  c.oauth_instance = self.oauth_instance
                end
                c
              end            
              alias_method_chain :connection, :oauth
            end
          end
        end
        
        def with_oauth(instance, &block)
          @oauth_instance = instance
          yield
          @oauth_instance = nil
        end
        
        def oauth_instance
          @oauth_instance || (superclass.respond_to?(:oauth_instance) ? superclass.oauth_instance : nil)
        end
      end
    
      module ActMethods
      end
    end
  end
end

ActiveResource::Base.class_eval { include ActiveResource::Acts::OAuthResource }